package common.loader {

	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	
	import util.Logger;
	
	public class BaseLoader extends URLStream {
		
		public var info:Info;
		public var domain:ApplicationDomain;
		public var handler:Function;
		public var started:Boolean;
		public var finished:Boolean;
		
		public static const MESSAGE:uint = 0;
		public static const TEXT:uint = 1;
		public static const IMAGE:uint = 2;
		public static const SWF:uint = 3;
		
		private static var loaderQueue:Array;
		
		public static function init(max:uint):void {
			loaderQueue = new Array();
			for (var i:int = 0; i<max; i++) {
				loaderQueue.push(new BaseLoader());
			}
		}
		
		public static function add(info:Info, callback:Function):void {
			var loader:BaseLoader = loaderQueue.shift() as BaseLoader;
			loader.handler = callback;
			loader.start(info);
		}

		public function BaseLoader() {
			super();
			
			started = false;
			finished = true;
			
			addEventListener(Event.COMPLETE, completeHandler);
			addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
			addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityHandler);
		}
		
		public function start(target:Info):void {
			info = target;
			started = true;
			finished = false;
			super.load(new URLRequest(info.url));
		}
		
		protected function completeHandler(event:Event):void {
			started = false;
			finished = true;
			if (handler != null) {
				var byteArray:ByteArray = new ByteArray();
				(event.target as BaseLoader).readBytes(byteArray);
				info.raw = byteArray;
				handler(info);
			}
			loaderQueue.push(this);
		}
		
		private function errorHandler(event:IOErrorEvent):void {Logger.error(event.toString())};
		private function securityHandler(event:SecurityErrorEvent):void {Logger.error(event.toString())};
	}
}